const { pool } = require('../config/db');
const bcrypt = require('bcryptjs');
const { ValidationError, NotFoundError } = require('../middleware/error');

class UserModel {
  // 通过用户名或邮箱查找用户
  static async findByLoginIdentifier(identifier) {
    try {
      const [rows] = await pool.execute(
        'SELECT * FROM users WHERE username = ? OR email = ?',
        [identifier, identifier]
      );
      return rows[0];
    } catch (error) {
      console.error('Error in findByLoginIdentifier:', error);
      throw error;
    }
  }

  // 通过ID查找用户
  static async findById(id) {
    try {
      const [rows] = await pool.execute(
        'SELECT id, username, email, nickname, created_at FROM users WHERE id = ?',
        [id]
      );
      return rows[0];
    } catch (error) {
      console.error('Error in findById:', error);
      throw error;
    }
  }

  // 创建新用户
  static async create({ username, email, password, nickname }) {
    try {
      // 检查用户名和邮箱是否已存在
      const [existingUsers] = await pool.execute(
        'SELECT username, email FROM users WHERE username = ? OR email = ?',
        [username, email]
      );

      const errors = {};
      existingUsers.forEach(user => {
        if (user.username === username) {
          errors.username = ['用户名已被使用'];
        }
        if (user.email === email) {
          errors.email = ['邮箱已被注册'];
        }
      });

      if (Object.keys(errors).length > 0) {
        throw new ValidationError('注册信息验证失败', errors);
      }

      // 对密码进行哈希处理
      const salt = await bcrypt.genSalt(10);
      const hashedPassword = await bcrypt.hash(password, salt);

      // 开始事务
      const connection = await pool.getConnection();
      try {
        await connection.beginTransaction();

        // 插入新用户
        const [result] = await connection.execute(
          'INSERT INTO users (username, email, password_hash, nickname, created_at) VALUES (?, ?, ?, ?, NOW())',
          [username, email, hashedPassword, nickname]
        );

        // 获取新创建的用户信息
        const [userRows] = await connection.execute(
          'SELECT id, username, email, nickname, created_at FROM users WHERE id = ?',
          [result.insertId]
        );

        await connection.commit();
        
        return userRows[0];
      } catch (error) {
        await connection.rollback();
        throw error;
      } finally {
        connection.release();
      }
    } catch (error) {
      console.error('Error in create:', error);
      throw error;
    }
  }

  // 更新用户信息
  static async updateProfile(userId, { nickname }) {
    const [result] = await pool.execute(
      'UPDATE users SET nickname = ? WHERE id = ?',
      [nickname, userId]
    );

    if (result.affectedRows === 0) {
      throw new NotFoundError('用户不存在');
    }

    return this.findById(userId);
  }

  // 更新用户密码
  static async updatePassword(userId, currentPassword, newPassword) {
    // 获取用户当前密码哈希
    const [rows] = await pool.execute(
      'SELECT password_hash FROM users WHERE id = ?',
      [userId]
    );

    if (rows.length === 0) {
      throw new NotFoundError('用户不存在');
    }

    // 验证当前密码
    const isValid = await bcrypt.compare(currentPassword, rows[0].password_hash);
    if (!isValid) {
      throw new ValidationError('密码更新失败', {
        current_password: ['当前密码不正确']
      });
    }

    // 对新密码进行哈希处理
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(newPassword, salt);

    // 更新密码
    await pool.execute(
      'UPDATE users SET password_hash = ? WHERE id = ?',
      [hashedPassword, userId]
    );

    return true;
  }

  // 重置密码（可选：用于忘记密码功能）
  static async resetPassword(email, token, newPassword) {
    const [rows] = await pool.execute(
      'SELECT id FROM users WHERE email = ? AND password_reset_token = ? AND password_reset_expires_at > NOW()',
      [email, token]
    );

    if (rows.length === 0) {
      throw new ValidationError('密码重置失败', {
        token: ['重置令牌无效或已过期']
      });
    }

    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(newPassword, salt);

    await pool.execute(
      'UPDATE users SET password_hash = ?, password_reset_token = NULL, password_reset_expires_at = NULL WHERE id = ?',
      [hashedPassword, rows[0].id]
    );

    return true;
  }

  // 新增：根据用户ID获取其所有收货地址
  static async getAddressesByUserId(userId) {
    console.log(`[UserModel.getAddressesByUserId] Fetching addresses for userId: ${userId}`);
    try {
      const query = `
        SELECT 
          id, 
          user_id, 
          recipient_name, 
          phone_number, 
          street_address, 
          city, 
          district, 
          province, 
          postal_code, 
          country, 
          is_default_shipping,
          created_at, 
          updated_at
        FROM user_addresses 
        WHERE user_id = ? 
        ORDER BY is_default_shipping DESC, updated_at DESC
      `;
      const [rows] = await pool.query(query, [userId]);
      console.log(`[UserModel.getAddressesByUserId] Found ${rows.length} addresses for userId: ${userId}`);
      return rows;
    } catch (error) {
      console.error(`[UserModel.getAddressesByUserId] Error fetching addresses for userId: ${userId}:`, error);
      throw error;
    }
  }

  // 添加新收货地址到数据库
  static async addAddress(userId, addressData) {
    console.log(`[UserModel.addAddress] Adding new address for userId: ${userId}`);
    try {
      const query = `
        INSERT INTO user_addresses (
          user_id,
          recipient_name,
          phone_number,
          street_address,
          city,
          district,
          province,
          postal_code,
          country,
          is_default_shipping,
          address_label
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
      `;
      
      const values = [
        userId,
        addressData.recipient_name,
        addressData.phone_number,
        addressData.street_address,
        addressData.city,
        addressData.district || null,
        addressData.province,
        addressData.postal_code || null,
        addressData.country || '中国',
        addressData.is_default_shipping || false,
        addressData.address_label || null
      ];

      // 如果新地址被设置为默认地址，需要先将其他地址的默认状态设为 false
      if (addressData.is_default_shipping) {
        await pool.query(
          'UPDATE user_addresses SET is_default_shipping = false WHERE user_id = ?',
          [userId]
        );
      }

      const [result] = await pool.query(query, values);
      console.log(`[UserModel.addAddress] New address added with id: ${result.insertId}`);
      
      // 获取新添加的地址信息
      const [newAddress] = await pool.query(
        'SELECT * FROM user_addresses WHERE id = ?',
        [result.insertId]
      );
      
      return newAddress[0];
    } catch (error) {
      console.error(`[UserModel.addAddress] Error adding address for userId: ${userId}:`, error);
      throw error;
    }
  }

  // 更新数据库中的指定收货地址
  static async updateAddress(addressId, addressData, userId) {
    console.log(`[UserModel.updateAddress] Updating address ${addressId} for userId: ${userId}`);
    try {
      // 首先检查地址是否存在且属于该用户
      const [existingAddress] = await pool.query(
        'SELECT * FROM user_addresses WHERE id = ? AND user_id = ?',
        [addressId, userId]
      );

      if (existingAddress.length === 0) {
        throw new NotFoundError('地址不存在或不属于当前用户');
      }

      const query = `
        UPDATE user_addresses 
        SET 
          recipient_name = ?,
          phone_number = ?,
          street_address = ?,
          city = ?,
          district = ?,
          province = ?,
          postal_code = ?,
          country = ?,
          is_default_shipping = ?,
          address_label = ?,
          updated_at = NOW()
        WHERE id = ? AND user_id = ?
      `;
      
      const values = [
        addressData.recipient_name,
        addressData.phone_number,
        addressData.street_address,
        addressData.city,
        addressData.district || null,
        addressData.province,
        addressData.postal_code || null,
        addressData.country || '中国',
        addressData.is_default_shipping || false,
        addressData.address_label || null,
        addressId,
        userId
      ];

      // 如果地址被设置为默认地址，需要先将其他地址的默认状态设为 false
      if (addressData.is_default_shipping) {
        await pool.query(
          'UPDATE user_addresses SET is_default_shipping = false WHERE user_id = ? AND id != ?',
          [userId, addressId]
        );
      }

      await pool.query(query, values);
      
      // 获取更新后的地址信息
      const [updatedAddress] = await pool.query(
        'SELECT * FROM user_addresses WHERE id = ?',
        [addressId]
      );
      
      return updatedAddress[0];
    } catch (error) {
      console.error(`[UserModel.updateAddress] Error updating address ${addressId} for userId: ${userId}:`, error);
      throw error;
    }
  }

  // 从数据库中删除指定收货地址
  static async deleteAddress(addressId, userId) {
    console.log(`[UserModel.deleteAddress] Deleting address ${addressId} for userId: ${userId}`);
    try {
      // 首先检查地址是否存在且属于该用户
      const [existingAddress] = await pool.query(
        'SELECT * FROM user_addresses WHERE id = ? AND user_id = ?',
        [addressId, userId]
      );

      if (existingAddress.length === 0) {
        throw new NotFoundError('地址不存在或不属于当前用户');
      }

      // 删除地址
      const [result] = await pool.query(
        'DELETE FROM user_addresses WHERE id = ? AND user_id = ?',
        [addressId, userId]
      );

      if (result.affectedRows === 0) {
        throw new Error('删除地址失败');
      }

      return true;
    } catch (error) {
      console.error(`[UserModel.deleteAddress] Error deleting address ${addressId} for userId: ${userId}:`, error);
      throw error;
    }
  }

  // 在数据库中设置默认地址
  static async setDefaultAddress(addressId, userId) {
    console.log(`[UserModel.setDefaultAddress] Setting address ${addressId} as default for userId: ${userId}`);
    try {
      // 首先检查地址是否存在且属于该用户
      const [existingAddress] = await pool.query(
        'SELECT * FROM user_addresses WHERE id = ? AND user_id = ?',
        [addressId, userId]
      );

      if (existingAddress.length === 0) {
        throw new NotFoundError('地址不存在或不属于当前用户');
      }

      // 开始事务
      const connection = await pool.getConnection();
      try {
        await connection.beginTransaction();

        // 先将该用户的所有地址设置为非默认
        await connection.query(
          'UPDATE user_addresses SET is_default_shipping = false WHERE user_id = ?',
          [userId]
        );

        // 将指定地址设置为默认
        await connection.query(
          'UPDATE user_addresses SET is_default_shipping = true WHERE id = ? AND user_id = ?',
          [addressId, userId]
        );

        await connection.commit();

        // 获取更新后的地址信息
        const [updatedAddress] = await pool.query(
          'SELECT * FROM user_addresses WHERE id = ?',
          [addressId]
        );

        return updatedAddress[0];
      } catch (error) {
        await connection.rollback();
        throw error;
      } finally {
        connection.release();
      }
    } catch (error) {
      console.error(`[UserModel.setDefaultAddress] Error setting default address ${addressId} for userId: ${userId}:`, error);
      throw error;
    }
  }
}

module.exports = UserModel; 